home *** CD-ROM | disk | FTP | other *** search
- PAGE ,132
- TITLE IBM-PC Mark/UnMark-Bad-Cluster Program, Version 2.20, 25-Aug-1986
-
- ;
- ; Written By Steven Georgiades
- ;
- ; IBM-PC/XT Mark/UnMark-Bad-Cluster Program
- ; This program will allow you to mark or unmark a cluster on your disk as
- ; bad. It should work under all versions of DOS 2.00 and higher, and should
- ; work on the PC, XT, AT, PCJr. and all compatibles. The programs is invoked
- ; as follows:
- ;
- ; MARK [d:] [/U | /M] n [[d:] [/U | /M] n [[...]]]
- ;
- ; d: Optional drive letter. If this is omitted, the default
- ; drive is used.
- ;
- ; /U Un-mark switch. The following clusters will be un-marked.
- ; If no switch is specified, Un-mark is assumed.
- ;
- ; /M Mark switch. The following clusters will be marked bad.
- ;
- ; n Cluster Number, in decimal. The first data cluster is 2.
- ; (Don't blame me. DOS defines it that way.)
- ;
- ;
- ; If you are using this program and find it of value, your
- ; contribution in any amount ($10.00 suggested) will be greatly
- ; appreciated. Makes checks payable to Steven M. Georgiades.
- ; Thank you.
- ;
- ; If you have any questions or comments about this or any other
- ; SMG program, write to me at the following address:
- ;
- ; Steven M. Georgiades
- ; 701-H South Hayward Street
- ; Anaheim, CA 92804
- ;
-
- CODE SEGMENT BYTE PUBLIC 'CODE'
-
- ASSUME CS:CODE,DS:CODE,ES:CODE,SS:CODE
-
- ORG 80H
-
- PARAM LABEL BYTE
-
- ORG 100H
-
- MARK: JMP BEGIN
-
- DIGIT DB "0123456789ABCDEF"
- SIGNON DB "Mark, Version 2.20",13,10,10,"$"
-
- CLSTMSG DB "Cluster XXXXX$"
- INVALID DB " does not exist!",7,13,10,"$"
-
- BADMSG DB " is already marked as bad",13,10,"$"
- INUSEMSG DB " is currently in use by a file",13,10,"$"
- RESVMSG DB " is reserved",13,10,"$"
-
- NOTBAD DB " is not marked as bad",13,10,"$"
-
- MARKMSG DB " has been marked as bad",13,10,"$"
- UNMRKMSG DB " has been un-marked as bad",13,10,"$"
-
- CLSTSEC DW ?
- CLSTTOT DW ?
- CLUST DW ?
- DRIVE DB ?
- EOF DW ?
- FATSEC DW ?
- FATSIZE DB ?
- FLAG DB 0
- OLDDRV DB -1
- SECSIZE DW ?
-
- BEGIN: MOV AH,9 ; Output Sign-On Message
- MOV DX,OFFSET SIGNON
- INT 21H
- MOV AH,19H ; Get Default Drive Number
- INT 21H
- MOV DRIVE,AL ; and Save
- MOV SI,OFFSET PARAM ; Set up Pointer to Parameter
- LODSB ; Read Parameter Length
- CBW
- MOV BX,AX
- MOV BYTE PTR [SI][BX],0 ; Terminate Parameter String
- STRIP: LODSB ; Strip Off Leading Whitespace
- CMP AL,' '
- JE STRIP
- CMP AL,9
- JE STRIP
- OR AL,AL ; If End-of-Parameter List,
- JNZ NOTDONE
- MOV AX,4C00H ; Exit to DOS
- INT 21H
- NOTDONE: CMP AL,'/' ; If Switch, Process
- JNE NOSWITCH
- LODSB ; Get Switch Letter
- AND AL,0DFH ; Convert to Upper Case
- CMP AL,'U' ; If '/U', Reset MARK Flag
- JE SWITCHU
- CMP AL,'M' ; If Not '/M', Next Character
- JNE STRIP
- MOV FLAG,-1 ; Else Set MARK Flag
- JMP SHORT STRIP
- SWITCHU: MOV FLAG,0 ; Reset MARK Flag
- JMP SHORT STRIP
- NOSWITCH: LODSB ; Get Drive Letter
- CMP AL,':'
- JNE NODRIVE
- INC SI
- AND AL,0DFH ; Convert to Upper Case
- SUB AL,'A' ; Convert to Drive Number
- MOV DRIVE,AL ; Save Drive Number
- JMP STRIP ; Get Next Paramter
- NODRIVE: SUB SI,2 ; ReUse Last Character
- CALL GET_WORD ; Read Cluster Number (Hex)
- MOV CLUST,DX ; Save Cluster Number
- MOV AL,DRIVE ; If Different Drive,
- CMP AL,OLDDRV
- JE DRV_OK
- PUSH SI ; Save Parameter Pointer
- MOV OLDDRV,AL ; Save New Drive
- MOV BX,OFFSET FATBUF ; Read Boot Record
- MOV CX,1
- MOV DX,0
- INT 25H
- POPF
- MOV AX,FATBUF[11] ; Read Sector Size and Save
- MOV SECSIZE,AX
- MOV AL,BYTE PTR FATBUF[13] ; Read Sectors/Cluster and Save
- XOR AH,AH
- MOV CLSTSEC,AX
- MOV BX,FATBUF[22] ; Read Sectors/FAT and Save
- MOV FATSEC,BX
- MOV AH,36H ; Get Total Data Clusters
- MOV DL,DRIVE
- INC DL
- INT 21H
- ADD DX,2
- MOV CLSTTOT,DX ; and Save
- MOV FATSIZE,3
- MOV EOF,0FF8H
- CMP DX,4081 ; If Necessary, Adjust FAT Size
- JLE FAT_OK
- MOV FATSIZE,4
- MOV EOF,0FFF8H
- FAT_OK: MOV AL,DRIVE ; Read FAT
- MOV CX,FATSEC
- MOV DX,1
- MOV BX,OFFSET FATBUF
- INT 25H
- POPF
- POP SI ; Restore Parameter Pointer
- DRV_OK: MOV BX,CLUST ; Get Cluster Number
- MOV AX,BX ; Convert Cluster No. to ASCII
- MOV DI,OFFSET CLSTMSG[13]
- CALL DEC5OUT
- CALL STRIP0 ; Strip Off Leading Zeroes
- MOV AH,9 ; Output Cluster Message
- MOV DX,OFFSET CLSTMSG
- INT 21H
- CMP BX,CLSTTOT ; If Invalid, Say So
- JAE CLST_BAD
- CMP BX,2
- JAE CLST_OK
- CLST_BAD: MOV DX,OFFSET INVALID
- JMP SHORT ERROUT
- CLST_OK: CALL NEXTCLST ; Get Next Cluster Number
- MOV AX,EOF ; Get EOF Value
- CMP FLAG,0 ; If /U, Unmark
- JE UNMARK
- OR BX,BX ; Else Mark
- JZ IS_FREE
- CMP BX,AX ; If Reserved,
- JB NOTINUSE
- IN_USE: MOV DX,OFFSET INUSEMSG
- JMP SHORT ERROUT ; Output Error Message
- NOTINUSE: DEC AX
- CMP BX,AX
- JNE NOT_BAD
- MOV DX,OFFSET BADMSG
- JMP SHORT ERROUT
- NOT_BAD: SUB AX,7
- CMP BX,AX
- JB IN_USE
- MOV DX,OFFSET RESVMSG
- JMP SHORT ERROUT
- IS_FREE: MOV BX,CLUST ; Get Cluster Number
- MOV AX,EOF ; New Value = Bad Cluster
- DEC AX
- MOV DX,OFFSET MARKMSG
- JMP WRT_FAT
- UNMARK: DEC AX
- CMP BX,AX ; If Not Bad,
- JE IS_BAD
- MOV DX,OFFSET NOTBAD
- ERROUT: MOV AH,9 ; Output Error Message
- INT 21H
- JMP STRIP
- IS_BAD: MOV BX,CLUST ; Get Cluster Number
- XOR AX,AX ; New Value = Good Cluster
- MOV DX,OFFSET UNMRKMSG
- WRT_FAT: PUSH DX
- CALL SETCLST
- PUSH SI ; Save Parameter Pointer
- MOV AL,DRIVE ; Write FAT #1
- MOV CX,FATSEC
- MOV DX,1
- MOV BX,OFFSET FATBUF
- INT 26H
- POPF
- MOV AL,DRIVE ; Write FAT #2
- MOV CX,FATSEC
- MOV DX,CX
- INC DX
- MOV BX,OFFSET FATBUF
- INT 26H
- POPF
- POP SI ; Restore Parameter Pointer
- MOV AH,9 ; Output UnMarked Message
- POP DX
- INT 21H
- JMP STRIP
-
- NEXTCLST: CMP FATSIZE,3 ; If FAT Size = 16 Bits,
- JE NEXT_12
- SHL BX,1 ; Simply Read Next Cluster #
- MOV BX,FATBUF[BX]
- RET ; Done
- NEXT_12: PUSH CX ; Save Registers
- MOV CX,BX ; Word # = Cluster # * 1.5
- SHL CX,1
- ADD BX,CX
- SHR BX,1
- MOV BX,FATBUF[BX]
- JNC NEXT_OK ; If Odd, Use 12 MSB's
- MOV CL,4
- SHR BX,CL
- NEXT_OK: AND BX,0FFFH ; Else Use 12 LSB's
- POP CX ; Restore Registers
- RET ; Done
-
- SETCLST: PUSH AX ; Save Registers
- PUSH BX
- CMP FATSIZE,3 ; If FAT Size = 16 Bits,
- JE SETC_12
- SHL BX,1 ; Simply Read Next Cluster #
- MOV FATBUF[BX],AX
- JMP SHORT SET_DONE ; Done
- SETC_12: PUSH CX ; Save Registers
- MOV CX,BX ; Word # = Cluster # * 1.5
- SHL CX,1
- ADD BX,CX
- SHR BX,1
- MOV CX,0F000H
- JNC SETC_OK ; If Odd, Use 12 MSB's
- MOV CL,4
- SHL AX,CL
- MOV CX,0FH
- SETC_OK: AND FATBUF[BX],CX
- OR FATBUF[BX],AX
- POP CX
- SET_DONE: POP BX
- POP AX
- RET ; Done
-
- GET_WORD: PUSH BX ; Save Register
- XOR DX,DX ; Value = 0
- GET_WRD1: LODSB ; Read Character
- CMP AL,'0' ; If Not Numeric, Done
- JB GET_WRD2
- CMP AL,'9'
- JA GET_WRD2
- SUB AL,'0' ; Convert to BCD
- CBW
- MOV BX,AX ; Value = Value*10+BCD
- MOV AX,10
- MUL DX
- ADD AX,BX
- MOV DX,AX
- JMP GET_WRD1 ; Repeat
- GET_WRD2: DEC SI
- POP BX ; Restore Register
- RET ; Done
-
- STRIP0: CMP BYTE PTR [DI],'0' ; If Character != '0', Done
- JNE STRIP1
- CMP BYTE PTR [DI+1],'0' ; If Next Character != Digit,
- JL STRIP1 ; Done
- CMP BYTE PTR [DI+1],'9'
- JG STRIP1
- MOV BYTE PTR [DI],' ' ; Change '0' to ' '
- INC DI ; Point to Next Character
- JMP SHORT STRIP0 ; Repeat
- STRIP1: RET ; Done
-
- DEC2OUT: PUSH AX ; Save Registers
- PUSH BX
- XOR AH,AH ; Clear AH
- MOV BL,10 ; AH=AX%10,AL=AX/10
- DIV BL
- ADD AX,'00' ; Convert to ASCII
- SUB DI,2
- MOV [DI],AX ; Store in String
- POP BX ; Restore Registers
- POP AX
- RET ; Done
-
- DEC4OUT: PUSH AX ; Save Registers
- PUSH BX
- MOV BL,100 ; AH=AX%100,AL=AX/100
- DIV BL
- XCHG AH,AL ; Convert 2 LSD's
- CALL DEC2OUT
- XCHG AH,AL ; Convert 2 MSD's
- CALL DEC2OUT
- POP BX ; Restore Registers
- POP AX
- RET ; Done
-
- DEC5OUT: PUSH AX ; Save Registers
- PUSH BX
- PUSH DX ; DX=AX%10000,AX=AX/10000
- MOV BX,10000
- XOR DX,DX
- DIV BX
- XCHG DX,AX ; Convert 4 LSD's
- CALL DEC4OUT
- XCHG DX,AX ; Convert MSD
- ADD AL,'0'
- SUB DI,1
- MOV [DI],AL
- POP DX ; Restore Registers
- POP BX
- POP AX
- RET ; Done
-
- FATBUF LABEL WORD
-
- CODE ENDS
-
- END MARK
-